Skip to content

Fixed rich text sorting order issue when used together with Sorting2D component#19084

Closed
raduangelescu wants to merge 2 commits intococos:v3.8.8from
raduangelescu:v3.8.8
Closed

Fixed rich text sorting order issue when used together with Sorting2D component#19084
raduangelescu wants to merge 2 commits intococos:v3.8.8from
raduangelescu:v3.8.8

Conversation

@raduangelescu
Copy link

@raduangelescu raduangelescu commented Nov 21, 2025

The RichText component was creating label and Sprite nodes that did not propagate the Sorting2D component that the RichText had. This resulted in incorrect render orders for rich text because all it's child nodes would render on the default layer with 0 sorting order.

This pull request fixes this issue: #19015

Example project archive:
richtextbadlayer_example.zip

Example of issue:
layer setup:
image

Before fix:
image

After fix:
image

Re: #

Changelog

  • Added Sorting2D components on label and image nodes of the richText node if the richText has a Sorting2d component on it. Updated their values with the ones from the richText node

Continuous Integration

This pull request:

  • needs automatic test cases check.

    Manual trigger with @cocos-robot run test cases afterward.

  • does not change any runtime related code or build configuration

    If any reviewer thinks the CI checks are needed, please uncheck this option, then close and reopen the issue.


Compatibility Check

This pull request:

  • changes public API, and have ensured backward compatibility with deprecated features.
  • affects platform compatibility, e.g. system version, browser version, platform sdk version, platform toolchain, language version, hardware compatibility etc.
  • affects file structure of the build package or build configuration which requires user project upgrade.
  • introduces breaking changes, please list all changes, affected features and the scope of violation.

Greptile Summary

  • Fixes RichText rendering order issue where child Label and Sprite nodes did not inherit Sorting2D properties from parent RichText components, causing incorrect layer ordering
  • Implements iOS-specific WebGL VAO invalidation fixes to handle buffer update synchronization issues in Safari's WebGL-to-Metal translation layer
  • Adds version tracking system for buffers and VAOs with hash-based staleness detection to prevent rendering corruption on iOS devices

Important Files Changed

Filename Overview
cocos/2d/components/rich-text.ts Fixed RichText to propagate Sorting2D properties to child nodes and sync values during runtime
cocos/gfx/webgl2/webgl2-commands.ts Added comprehensive iOS VAO invalidation logic with buffer version tracking and forced rebinding
cocos/gfx/webgl/webgl-commands.ts Implemented iOS-specific buffer versioning and VAO recreation to fix WebGL-to-Metal rendering issues
cocos/gfx/webgl2/webgl2-gpu-objects.ts Added interface definitions for buffer updateVersion and VAO version tracking fields
cocos/gfx/webgl/webgl-gpu-objects.ts Added optional updateVersion and vaoVersions fields to GPU buffer and input assembler interfaces

Confidence score: 4/5

  • This PR addresses well-documented issues with solid implementation patterns but involves complex graphics pipeline changes that require careful testing
  • Score reflects the iOS VAO fixes being platform-specific workarounds for WebGL-to-Metal translation issues, plus the RichText change affecting UI component hierarchies
  • Pay close attention to WebGL command files which implement intricate buffer versioning logic and VAO recreation mechanisms that could impact rendering performance

Sequence Diagram

sequenceDiagram
    participant User
    participant WebGL2CmdFuncUpdateBuffer
    participant Device
    participant GL as "WebGL Context"
    participant VAO as "VAO Cache"
    participant IA as "Input Assembler"

    User->>WebGL2CmdFuncUpdateBuffer: "Update buffer data"
    WebGL2CmdFuncUpdateBuffer->>Device: "Check if iOS"
    alt iOS Platform
        WebGL2CmdFuncUpdateBuffer->>WebGL2CmdFuncUpdateBuffer: "Increment updateVersion++"
        WebGL2CmdFuncUpdateBuffer->>VAO: "Unbind current VAO"
        WebGL2CmdFuncUpdateBuffer->>GL: "gl.bindVertexArray(null)"
        WebGL2CmdFuncUpdateBuffer->>IA: "Invalidate input assembler cache"
    end
    WebGL2CmdFuncUpdateBuffer->>GL: "Bind target buffer"
    WebGL2CmdFuncUpdateBuffer->>GL: "gl.bufferSubData() or gl.bufferData()"
    
    Note over User,IA: Later during rendering...
    
    User->>WebGL2CmdFuncBindStates: "Bind rendering states"
    WebGL2CmdFuncBindStates->>Device: "Check if iOS and VAO needed"
    alt iOS Platform and VAO Required
        WebGL2CmdFuncBindStates->>WebGL2CmdFuncBindStates: "Compute current buffer versions"
        WebGL2CmdFuncBindStates->>VAO: "Check cached VAO version"
        alt Version Mismatch
            WebGL2CmdFuncBindStates->>GL: "Delete old VAO"
            WebGL2CmdFuncBindStates->>GL: "Create new VAO"
            WebGL2CmdFuncBindStates->>VAO: "Store new version hash"
        end
    end
    WebGL2CmdFuncBindStates->>GL: "Bind VAO for rendering"
Loading

@github-actions
Copy link

github-actions bot commented Nov 21, 2025

Code Size Check Report

Wechat (WASM) Before After Diff
2D Empty (legacy pipeline) 1009738 bytes 1010354 bytes ⚠️ +616 bytes
2D All (legacy pipeline) 2675347 bytes 2678922 bytes ⚠️ +3575 bytes
2D All (new pipeline) 2767083 bytes 2770658 bytes ⚠️ +3575 bytes
(2D + 3D) All 10024081 bytes 10026298 bytes ⚠️ +2217 bytes
Web (WASM + ASMJS) Before After Diff
(2D + 3D) All 16843143 bytes 16845360 bytes ⚠️ +2217 bytes

Interface Check Report

! WARNING this pull request has changed these public interfaces:

@@ -3035,9 +3035,13 @@
         protected _layoutDirty: boolean;
         protected _lineOffsetX: number;
         protected _updateRichTextStatus: () => void;
         protected _labelChildrenNum: number;
+        protected _currentSortingLayer: number;
+        protected _currentSortingOrder: number;
+        protected _sorting2d: Sorting2D | null;
         constructor();
+        protected __preload(): void;
         onLoad(): void;
         onEnable(): void;
         onDisable(): void;
         onRestore(): void;
@@ -3066,8 +3070,9 @@
         protected _convertLiteralColorValue(color: string): math.Color;
         protected _applyTextAttribute(labelSeg: __private._cocos_2d_components_rich_text__ISegment): void;
         protected _applyLayer(): void;
         protected _resetLabelState(label: Label): void;
+        protected update(dt: number): void;
     }
     /**
      * @en
      * Graphics component.

@greptile-apps
Copy link

greptile-apps bot commented Dec 29, 2025

Greptile found no issues!

From now on, if a review finishes and we haven't found any issues, we will not post anything, but you can confirm that we reviewed your changes in the status check section.

This feature can be toggled off in your Code Review Settings by deselecting "Create a status check for each PR".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant